import random

import cv2
import time
import numpy as np
import os
import base64

from common.logger import logger

from PIL import Image

def get_gap(f1,f2):
    """
    获取缺口偏移量  f1,f2为两个图片地址
    :param bg: 带缺口图片
    :param full: 不带缺口图片
    :return:
    """
    bg = Image.open(f1)
    full = Image.open(f2)
    for x in range(1, 259):
        for y in range(1, 115):
            if not is_similar(bg, full, x, y):
                # 判断成立 表示xy这个点 两张图不一样
                # 因为本身滑块有点距离根据不同屏幕分辨率大小可能有一定的误差值
                return x - 8


def is_similar(image1, image2, x, y):
    pixel1 = image1.getpixel((x, y))
    pixel2 = image2.getpixel((x, y))
    for i in range(0, 3):
        if abs(pixel1[i] - pixel2[i]) >= 50:
            return
    return True


def save_grayscale_image(path: str, out_path: str = None) -> str:
    """保存灰度图像"""
    if out_path is None:
        out_path = path
    # 打开图像
    image: Image = Image.open(path)
    # 将图像转换为灰度
    grayscale_image = image.convert('L')
    # grayscale_image.show()
    # 保存灰度图像
    grayscale_image.save(out_path)
    return os.path.join(os.path.dirname(__file__), out_path)


def read_image(path: str) -> str:
    """"二值化处理"""
    # 读取灰度图像
    image_gray = cv2.imread(path, 0)

    # 二值化处理
    ret, image_binary = cv2.threshold(image_gray, 127, 255, cv2.THRESH_BINARY)

    # 显示二值化结果
    cv2.imshow("Binary Image", image_binary)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    logger.info(image_binary)
    # 保存为图片
    out_path = "binary" + path
    cv2.imwrite(out_path, image_binary)
    return os.path.join(os.path.dirname(__file__), out_path)


def orb(known_image_path: str, target_image_path: str):
    """暴力匹配器匹配特征"""
    # 加载已知图像
    known_image = cv2.imread(known_image_path)

    # 加载目标图像
    target_image = cv2.imread(target_image_path)

    # 创建ORB特征检测器
    detector = cv2.ORB_create()

    # 在已知图像中检测和计算特征描述符
    known_keypoints, known_descriptors = detector.detectAndCompute(known_image, None)

    # 在目标图像中检测和计算特征描述符
    target_keypoints, target_descriptors = detector.detectAndCompute(target_image, None)

    # 创建暴力匹配器
    matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

    # 使用暴力匹配器匹配特征
    matches = matcher.match(known_descriptors, target_descriptors)

    # 将匹配结果按距离排序
    matches = sorted(matches, key=lambda x: x.distance)

    result = cv2.drawMatches(known_image, known_keypoints, target_image, target_keypoints, matches[:10], None, flags=2)

    # 显示匹配结果
    cv2.imshow('Result', result)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()


def denoise_image(image_path, out_path):
    # 读取图片
    img = cv2.imread(image_path)

    # 将图像转换为灰度图像
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 使用高斯滤波进行降噪
    denoised = cv2.GaussianBlur(gray, (3, 3), 0)

    # 显示降噪后的图像
    cv2.imshow("Denoised Image", denoised)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    # 保存为图片
    cv2.imwrite(out_path, denoised)
    return os.path.join(os.path.dirname(__file__), out_path)

def center_imag(path):
    img = cv2.imread(path)
    noise = np.random.normal(0, 50, size=img.size).reshape(img.shape[0], img.shape[1], img.shape[2])
    # # 加上噪声
    img = img + noise
    img = np.clip(img, 0, 255)
    img = img / 255

    # 中值滤波
    img1 = np.transpose(img, (2, 0, 1))  # 转换成[channel,H,W]形式
    m = 3  # 定义滤波核大小
    n = 3
    rec_img = np.zeros((img1.shape[0], img1.shape[1] - m + 1, img1.shape[2] - n + 1))
    for channel in range(rec_img.shape[0]):
        for i in range(rec_img[channel].shape[0]):
            for j in range(rec_img[channel].shape[1]):
                rec_img[channel][i, j] = np.median(img1[channel][i:i + m, j:j + n])
    rec_img = np.transpose(rec_img, (1, 2, 0))

    cv2.imshow('median', rec_img)
    cv2.waitKey(0)

def save_base64_image(code, name=None):
    """ 保存base64 编码"""
    imagedata = base64.b64decode(code)
    file_name = os.path.join(os.path.dirname(__file__), str(time.time()) if name is None else name) + ".png"
    with open(file_name, "wb") as f:
        f.write(imagedata)
        f.close()
    return file_name





def get_track(distance):
    '''
      滑块移动轨迹
      初速度 v =0
      单位时间 t = 0.2
      位移轨迹 tracks = []
      当前位移 ccurrent = 0
      :param distance: 总距离
      :return:
      '''
    v = 5
    t = 0.5
    tracks = []
    current = 0
    mid = distance * 4 / 5
    while current < distance:
        if current < mid:
            a = random.randint(2, 3)  # 加速运动
        else:
            a = -random.randint(2, 4)  # 减速运动
        v0 = v
        s = v0 * t + 0.5 * a * (t ** 2)
        current += s
        tracks.append(round(s))
        v = v0 + a * t
    # if current > distance:
    #     tracks.append(int(-current-distance))
    random.shuffle(tracks)
    return tracks


